home *** CD-ROM | disk | FTP | other *** search
- /* net/rom user command processing
- * Copyright 1989 by Daniel M. Frank, W9NK. Permission granted for
- * non-commercial distribution only.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <time.h>
- #include <string.h>
- #include "global.h"
- #include "config.h"
- #ifdef NETROM
- #include "mbuf.h"
- #include "ax25.h"
- #include "mailbox.h"
- #include "netrom.h"
- #include "nr4.h"
- #include "timer.h"
- #include "iface.h"
- #include "cmdparse.h"
- #include "session.h"
- #include "socket.h"
- #include "commands.h"
- #include "files.h"
-
- /* Nodes message broadcast address: "NODES" in shifted ASCII */
- /* defined in ax25rout.c: Ax25multi[1] */
-
- char Nr4user[AXALEN];
-
- char *Nr4states[] = {
- "Disconnected",
- "Conn Pending",
- "Connected",
- "Disc Pending",
- "Listen"
- } ;
-
- char *Nr4reasons[] = {
- "Normal",
- "By Peer",
- "Timeout",
- "Reset",
- "Refused"
- } ;
-
- int Nr_save = 1; /* NET/ROM Route Save on by default */
- int donrsave __ARGS((void));
-
- static char *Nodelist = NULLCHAR;
- static struct timer Nodetimer ; /* timer for nodes broadcasts */
- static struct timer Obsotimer ; /* timer for aging routes */
- static char badcall[] = "Bad destination callsign\n";
- static char badnb[] = "Bad neighbor callsign\n";
-
- int
- doroutedump(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- #define MAX_LES_ROUTES 150
-
- struct nrroute_tab *rp ;
- char buf[18], temp[18], les_routes[MAX_LES_ROUTES][18], *cp;
- int count = 0, column = 1, in, out, i;
-
- for (i = 0 ; i < NRNUMCHAINS ; i++) {
- for (rp = Nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rp->next) {
- if(count > MAX_LES_ROUTES - 1)
- break;
- strcpy(buf,rp->alias) ;
- /* remove trailing spaces */
- if ((cp = strchr(buf,' ')) == NULLCHAR)
- cp = &buf[strlen(buf)] ;
- if (cp != buf) /* don't include colon for null alias */
- *cp++ = ':' ;
- pax25(cp,rp->call) ;
- if(argc == 9) {
- count++;
- strcpy(les_routes[count],buf);
- continue;
- }
- if(strstr(buf,"TCP") != NULL
- || strstr(buf,"NOS") != NULL
- || strstr(buf,"IP") != NULL) {
- count++;
- strcpy(les_routes[count],buf);
- }
- }
- if(count > MAX_LES_ROUTES - 1) {
- tprintf("\nOnly %d routes displayed\n",MAX_LES_ROUTES);
- break;
- }
- }
- for (out = 1; out < count; out++)
- for (in = out+1; in < count+1; in++)
- if (strcmp(les_routes[out],les_routes[in]) > 0 ) {
- strcpy(temp, les_routes[in]);
- strcpy(les_routes[in], les_routes[out]);
- strcpy(les_routes[out], temp);
- }
-
- for(i = 1; i <= count; i++) {
- tprintf("%-16s ", les_routes[i]);
- if( column++ == 4) {
- tputc('\n');
- column = 1;
- }
- }
- if(column != 1)
- tputc('\n');
- return 0 ;
- }
-
- /* print detailed information on an individual route */
- int
- dorouteinfo(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- struct nrroute_tab *rp ;
- struct nr_bind *bp ;
- struct nrnbr_tab *np ;
- char dest[AXALEN], neighbor[AXBUF], alias[AXBUF], *cp;
-
- if (setcall(dest,argv[1]) == -1) {
- tputs (badcall);
- return -1 ;
- }
-
- if(putalias(alias,argv[1],0) != -1
- && (cp = find_nralias(alias)) != NULLCHAR)
- memcpy(dest,cp,AXALEN);
-
- if((rp = find_nrroute(dest)) == NULLNRRTAB) {
- if(argc < 9)
- tprintf("*** no route to %s\n",pax25(neighbor,dest)) ;
- return -1 ;
- }
-
- for (bp = rp->routes ; bp != NULLNRBIND ; bp = bp->next) {
- np = bp->via ;
- if(tprintf("%1s %3d %3d %-8s %s\n",
- (bp->flags & NRB_PERMANENT ? "P" :
- bp->flags & NRB_RECORDED ? "R" : " "),
- bp->quality,bp->obsocnt,
- Nrifaces[np->iface].iface->name,
- pax25(neighbor,np->call)) == EOF)
- break;
- }
- return 0 ;
- }
-
- /* convert a null-terminated alias name to a blank-filled, upcased */
- /* version. Return -1 on failure. */
- int
- putalias(to,from,complain)
- char *to, *from ;
- int complain ;
- {
- int len, i ;
-
- if ((len = strlen(from)) > ALEN) {
- if (complain)
- tputs ("Max six chars\n") ;
- return -1 ;
- }
-
- for (i = 0 ; i < ALEN ; i++) {
- if (i < len) {
- if (islower(*from))
- *to++ = toupper(*from++) ;
- else
- *to++ = *from++ ;
- }
- else
- *to++ = ' ' ;
- }
-
- *to = '\0' ;
- return 0 ;
- }
-
- /* find a netrom interface, gives a msg if 'msg' is set != 0 */
- static int near
- nrif_lookup(call,msg)
- char *call;
- int msg;
- {
- int i;
-
- for (i = 0 ; i < Nr_numiface ; i++)
- if (!strcmp(Nrifaces[i].iface->name,call))
- break ;
- if (i == Nr_numiface) {
- if(msg)
- tprintf(Badif,call);
- return -1 ;
- }
- return i;
- }
-
- /* Add a route */
- static int
- dorouteadd(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- char alias[AXALEN], dest[AXALEN], neighbor[AXALEN];
- unsigned quality ;
- int i ;
-
- /* format alias (putalias prints error message if necessary) */
- if (putalias(alias,argv[1],1) == -1)
- return -1 ;
-
- /* format destination callsign */
- if (setcall(dest,argv[2]) == -1) {
- tputs(badcall);
- return -1 ;
- }
-
- if((i = nrif_lookup(argv[3],1)) == -1)
- return -1;
-
- /* format neighbor address string */
- if (setcall(neighbor,argv[5]) == -1) {
- tputs(badcall);
- return -1;
- }
- #ifdef XXX
- /* Change from 871225 -- no digis in net/rom table */
- if (argc > 6)
- tputs("digis given: set route with ax25 route cmd\n");
- #endif
- /* get and check quality value */
- quality = (unsigned)min(atoi(argv[4]),255);
-
- return nr_routeadd(alias,dest,i,quality,neighbor,1,0) ;
- }
-
-
- /* drop a route */
- static int
- doroutedrop(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- char dest[AXALEN], neighbor[AXALEN] ;
- int i ;
-
- /* format destination and neighbor callsigns */
- if (setcall(dest,argv[1]) == -1) {
- tputs(badcall);
- return -1 ;
- }
- if (setcall(neighbor,argv[2]) == -1) {
- tputs(badnb);
- return -1 ;
- }
-
- if((i = nrif_lookup(argv[3],1)) == -1)
- return -1;
-
- return nr_routedrop(dest,neighbor,i) ;
- }
-
- /* make an interface available to net/rom */
- static int
- dointerface(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- int i ;
- struct iface *ifp ;
-
- if (Nr_iface == NULLIF)
- nr_attach(0,0,p);
-
- if (Nr_numiface >= NRNUMIFACE) {
- tprintf("Max %d NET/ROM ifaces\n",NRNUMIFACE);
- return 1 ;
- }
- if((ifp = if_lookup(argv[1])) == NULLIF){
- tprintf(Badif,argv[1]);
- return 1;
- }
- for (i = 0 ; i < Nr_numiface ; i++)
- if (Nrifaces[i].iface == ifp) {
- tprintf("Iface %s already registered\n",argv[1]) ;
- return 1 ;
- }
-
- Nrifaces[Nr_numiface].iface = ifp ;
-
- if (putalias(Nrifaces[Nr_numiface].alias,argv[2],1) == -1)
- return 1 ;
-
- Nrifaces[Nr_numiface].quality = (unsigned)min(atoi(argv[3]),255);
- Nr_numiface++ ; /* accept this interface */
- return 0 ;
- }
-
- static void
- donodetick()
- {
- if(Nr_numiface) {
- int i;
-
- stop_timer(&Nodetimer);
-
- for (i = 0 ; i < Nr_numiface ; i++)
- nr_bcnodes(i,Ax25multi[1]) ;
-
- if(strchr(Nodelist,'*') != NULLCHAR) {
- char *cp1 = strxdup(Nodelist);
- char *cp = strtok(cp1,"*");
-
- while((cp = strtok(NULL,"*")) != NULLCHAR)
- nr_bcnodes(Nr_numiface - 1,cp);
-
- xfree(cp1);
- }
- }
- /* restart timer */
- start_timer(&Nodetimer);
- }
-
- /* Broadcast nodes list on named interface. */
- static int
- dobcnodes(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- int j;
- char call[AXALEN];
-
- int i = nrif_lookup(argv[1],(argc < 3) ? 1 : 0);
-
- if(argc < 3) {
- if(i == -1)
- return -1;
- nr_bcnodes(i,Ax25multi[1]);
- return 0;
- }
- if(i == -1) {
- argc++;
- argv--;
- }
- if(Nodelist) {
- xfree(Nodelist);
- Nodelist = NULLCHAR;
- }
- Nodelist = cxallocw(argc,AXBUF);
-
- for(j = 1; j < argc; j++) {
- if(setcall(call,argv[j]) == -1)
- continue;
- strcat(Nodelist,call);
- strcat(Nodelist,"*");
- }
- donodetick();
- return 0;
- }
-
- /* Set outbound node broadcast interval */
- static int
- donodetimer(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2){
- tprintf("Nodetimer %lu/%lu s\n",
- read_timer(&Nodetimer)/1000L,
- dur_timer(&Nodetimer)/1000L);
- return 0;
- }
- /* in case it's already running */
- stop_timer(&Nodetimer) ;
- /* what to call on timeout */
- Nodetimer.func = (void (*) __ARGS((void *))) donodetick;
- Nodetimer.arg = NULLCHAR; /* dummy value */
- set_timer(&Nodetimer,atol(argv[1]) * 1000L); /* set timer duration */
- start_timer(&Nodetimer); /* and fire it up */
- return 0;
- }
-
- /* Go through the routing table, reducing the obsolescence count of
- * non-permanent routes, and purging them if the count reaches 0
- */
- static void
- doobsotick()
- {
- struct nrnbr_tab *np ;
- struct nrroute_tab *rp, *rpnext ;
- struct nr_bind *bp, *bpnext ;
- int i ;
-
- stop_timer(&Obsotimer);
-
- for (i = 0 ; i < NRNUMCHAINS ; i++) {
- for (rp = Nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rpnext) {
- rpnext = rp->next ; /* save in case we free this route */
- for (bp = rp->routes ; bp != NULLNRBIND ; bp = bpnext) {
- bpnext = bp->next ; /* in case we free this binding */
- if (bp->flags & NRB_PERMANENT) /* don't age these */
- continue ;
- if (--bp->obsocnt == 0) { /* time's up! */
- if (bp->next != NULLNRBIND)
- bp->next->prev = bp->prev ;
- if (bp->prev != NULLNRBIND)
- bp->prev->next = bp->next ;
- else
- rp->routes = bp->next ;
- rp->num_routes-- ; /* one less binding */
- np = bp->via ; /* find the neighbor */
- xfree((char *)bp) ; /* now we can free the bind */
- /* Check to see if we can free the neighbor */
- if (--np->refcnt == 0) {
- if (np->next != NULLNTAB)
- np->next->prev = np->prev ;
- if (np->prev != NULLNTAB)
- np->prev->next = np->next ;
- else {
- Nrnbr_tab[nrhash(np->call)] = np->next ;
- }
- xfree((char *)np) ; /* free the storage */
- }
- }
- }
- if (rp->num_routes == 0) { /* did we free them all? */
- if (rp->next != NULLNRRTAB)
- rp->next->prev = rp->prev ;
- if (rp->prev != NULLNRRTAB)
- rp->prev->next = rp->next ;
- else
- Nrroute_tab[i] = rp->next ;
-
- xfree((char *)rp) ;
- }
- }
- }
- start_timer(&Obsotimer) ;
- }
-
- /* Set timer for aging routes */
- static int
- doobsotimer(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc < 2){
- tprintf("Obsotimer %lu/%lu s\n",
- read_timer(&Obsotimer)/1000L,
- dur_timer(&Obsotimer)/1000L);
- return 0;
- }
- /* just in case it's already running */
- stop_timer(&Obsotimer) ;
- /* what to call on timeout */
- Obsotimer.func = (void (*) __ARGS((void *))) doobsotick;
- Obsotimer.arg = NULLCHAR; /* dummy value */
- set_timer(&Obsotimer,atol(argv[1]) * 1000L); /* set timer duration */
- start_timer(&Obsotimer); /* and fire it up */
- return 0;
- }
-
- /* display a list of <callsign,interface> pairs from the filter
- * list.
- */
- static int
- donfdump()
- {
- int i, column = 1 ;
- struct nrnf_tab *fp ;
- char buf[16] ;
-
- for (i = 0 ; i < NRNUMCHAINS ; i++)
- for (fp = Nrnf_tab[i] ; fp != NULLNRNFTAB ; fp = fp->next) {
- pax25(buf,fp->neighbor) ;
- tprintf("%-7s %-8s %-3d ",
- buf,Nrifaces[fp->iface].iface->name, fp->quality) ;
- if (column++ == 3) {
- if(tputs("\n") == EOF)
- return 0;
- column = 1 ;
- }
- }
-
- if (column != 1)
- tputs("\n") ;
-
- return 0 ;
- }
-
- /* add an entry to the filter table */
- static int
- donfadd(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- char neighbor[AXALEN] ;
- int i ;
- unsigned qual = (argc >= 4) ? atoi(argv[3]) : Nrifaces[i].quality;
-
- /* format callsign */
- if (setcall(neighbor,argv[1]) == -1) {
- tputs(badnb);
- return -1 ;
- }
-
- if((i = nrif_lookup(argv[2],1)) == -1)
- return -1;
-
- return nr_nfadd(neighbor,i,qual) ;
- }
-
- /* drop an entry from the filter table */
- static int
- donfdrop(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- char neighbor[AXALEN] ;
- int i ;
-
- /* format neighbor callsign */
- if (setcall(neighbor,argv[1]) == -1) {
- tputs(badnb);
- return -1 ;
- }
-
- if((i = nrif_lookup(argv[2],1)) == -1)
- return -1;
-
- return nr_nfdrop(neighbor,i) ;
- }
-
- /* nodefilter mode subcommand */
- static int
- donfmode(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- if (argc < 2) {
- tputs("Filter mode: ");
- switch (Nr_nfmode) {
- case NRNF_NOFILTER:
- tputs("none\n") ;
- break ;
- case NRNF_ACCEPT:
- tputs("accept\n") ;
- break ;
- case NRNF_REJECT:
- tputs("reject\n") ;
- break ;
- default:
- tputs("unknown\n") ;
- }
- } else {
- switch (tolower(argv[1][0])) {
- case 'n':
- Nr_nfmode = NRNF_NOFILTER ;
- break ;
- case 'a':
- Nr_nfmode = NRNF_ACCEPT ;
- break ;
- case 'r':
- Nr_nfmode = NRNF_REJECT ;
- break ;
- default:
- tputs("Usage: mode <accept|reject|none>\n");
- return -1 ;
- }
- }
- return 0;
- }
-
- /* nodefilter command multiplexer */
- static int
- donodefilter(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- struct cmds Nfcmds[] = {
- "add", donfadd, 0, 3,
- "netrom nodefilter add <neighbor> <iface> [<quality>]",
- "drop", donfdrop, 0, 3,
- "netrom nodefilter drop <neighbor> <iface>",
- "mode", donfmode, 0, 0, NULLCHAR,
- NULLCHAR,
- } ;
-
- if (argc < 2) {
- donfdump() ;
- return 0 ;
- }
- return subcmd(Nfcmds,argc,argv,p) ;
- }
-
- /* netrom network packet time-to-live initializer */
- static int
- donrttl(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setshort(&Nr_ttl,"TTL",argc,argv);
- }
-
- /* verbose route broadcast */
- static int
- donrverbose(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setbool(&Nr_verbose,"Verbose",argc,argv);
- }
-
- /* allow automatic derating of netrom routes on link failure */
- static int
- donrderate(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- extern int Nr_derate;
-
- return setbool(&Nr_derate,"Derate",argc,argv);
- }
-
- /* promiscuous acceptance of broadcasts */
- static int
- donrpromisc(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- extern int Nr_promisc;
-
- return setbool(&Nr_promisc,"Promiscuous",argc,argv);
- }
-
- /* Initiate a NET/ROM transport connection */
- static int
- donrconnect(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- char *np ;
- struct sockaddr_nr lsocket, fsocket;
- char alias[AXBUF];
- struct session *sp;
-
- /* Get a session descriptor */
- if ((sp = newsession(argv[1],NRSESSION,1,1)) == NULLSESSION) {
- tputs(Nosess);
- return 1;
- }
-
- if((sp->s = socket(AF_NETROM,SOCK_SEQPACKET,0)) == -1){
- tputs(Nosocket);
- goto quit;
- }
- lsocket.nr_family = AF_NETROM;
- /* Set up our local username, bind would use Mycall instead */
- memcpy(lsocket.nr_addr.user,Nr4user,AXALEN);
- /* Putting anything else than Mycall here will not work */
- memcpy(lsocket.nr_addr.node,Mycall,AXALEN);
- bind(sp->s,(char *)&lsocket,sizeof(struct sockaddr_nr));
-
- /* See if the requested destination could be an alias, and */
- /* find and use it if it is. Otherwise assume it is an ax.25 */
- /* address. */
-
- if (putalias(alias,argv[1],0) != -1 &&
- (np = find_nralias(alias)) != NULLCHAR) {
- memcpy(fsocket.nr_addr.user,np,AXALEN) ;
- memcpy(fsocket.nr_addr.node,np,AXALEN) ;
- } else { /* parse ax25 callsign */
- /* Only the user callsign of the remote station is never used by */
- /* NET/ROM, but it is needed for the psocket() call. */
- setcall(fsocket.nr_addr.user,argv[1]);
- setcall(fsocket.nr_addr.node,argv[1]);
- }
- fsocket.nr_family = AF_NETROM;
- pax25(alias,fsocket.nr_addr.node);
- if(!(tel_connect(sp, (char *)&fsocket, sizeof(struct sockaddr_nr))))
- return 0;
- quit:
- keywait(NULLCHAR,1);
- freesession(sp);
- return 1;
- }
-
- /* Reset a net/rom connection abruptly */
- static int
- donrreset(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct nr4cb *cb = (struct nr4cb *)htol(argv[1]);
-
- if(!nr4valcb(cb)){
- tputs(Notval);
- return 1;
- }
- reset_nr4(cb);
- return 0;
- }
-
- /* Allows a manual forced close on a net/rom connection */
- static int
- donrclose(int argc,char *argv[],void *p)
- {
- struct nr4cb *cb = (struct nr4cb *)htol(argv[1]);
-
- if(!nr4valcb(cb)) {
- tputs(Notval);
- return 1;
- }
- disc_nr4(cb);
- return 0;
- }
-
- /* Force retransmission on a net/rom connection */
- static int
- donrkick(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct nr4cb *cb = (struct nr4cb *)htol(argv[1]);
-
- if(!nr4valcb(cb)){
- tputs(Notval);
- return 1;
- }
- return kick_nr4(cb);
- }
-
- /* netrom transport ACK delay timer */
- static int
- donracktime(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setintrc(&Nr4acktime,"Ack delay",argc,argv,1,60);
- }
-
- /* netrom transport choke timeout */
- static int
- donrchoketime(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setintrc(&Nr4choketime,"Choke timeout",argc,argv,10,3600);
- }
-
- /* netrom transport initial round trip time */
-
- static int
- donrirtt(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setintrc(&Nr4irtt,"IRTT",argc,argv,5,360);
- }
-
- /* netrom transport receive queue length limit. This is the */
- /* threshhold at which we will CHOKE the sender. */
-
- static int
- donrqlimit(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setintrc(&Nr4qlimit,"Queue limit",argc,argv,1,4096);
- }
-
- /* Display or change our NET/ROM username */
- static int
- donruser(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char buf[AXBUF];
-
- if(argc < 2){
- tprintf("%s\n",pax25(buf,Nr4user));
- return 0;
- }
- if(setcall(Nr4user,argv[1]) == -1)
- return -1;
- Nr4user[ALEN] |= E;
- return 0;
- }
-
- /* netrom transport maximum window. This is the largest send and */
- /* receive window we may negotiate */
-
- static int
- donrwindow(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setintrc(&Nr4window,"Window",argc,argv,1,NR4MAXWIN);
- }
-
- /* netrom transport maximum retries. This is used in connect and */
- /* disconnect attempts; I haven't decided what to do about actual */
- /* data retries yet. */
-
- static int
- donrretries(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setshort(&Nr4retries,"Retry limit",argc,argv);
- }
-
- /* Display the status of NET/ROM connections */
-
- static int
- donrstatus(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- int i ;
- struct nr4cb *cb ;
- char luser[AXBUF], ruser[AXBUF], node[AXBUF] ;
-
- if (argc < 2) {
- tputs(" &CB Snd-W Snd-Q Rcv-Q LUser RUser @Node State\n");
- for (i = 0 ; i < NR4MAXCIRC ; i++) {
- if ((cb = Nr4circuits[i].ccb) == NULLNR4CB)
- continue ;
- pax25(luser,cb->local.user) ;
- pax25(ruser,cb->remote.user) ;
- pax25(node,cb->remote.node) ;
- if(tprintf("%8lx %3d %5d %5d %9s %9s %-9s %s\n",
- ptol(cb), cb->nbuffered, len_q(cb->txq),
- len_p(cb->rxq), luser, ruser, node,
- Nr4states[cb->state]) == EOF)
- break;
- }
- return 0 ;
- }
-
- cb = (struct nr4cb *)htol(argv[1]) ;
- if (!nr4valcb(cb)) {
- tputs(Notval) ;
- return 1 ;
- }
-
- donrdump(cb) ;
- return 0 ;
- }
-
- /* Dump one control block */
-
- void
- donrdump(cb)
- struct nr4cb *cb ;
- {
- char luser[AXBUF], ruser[AXBUF], node[AXBUF] ;
- unsigned seq ;
- struct nr4txbuf *b ;
- struct timer *t ;
-
- pax25(luser,cb->local.user) ;
- pax25(ruser,cb->remote.user) ;
- pax25(node,cb->remote.node) ;
-
- tprintf("Local: %s %d/%d Remote: %s @ %s %d/%d State: %s\n",
- luser, cb->mynum, cb->myid, ruser, node,
- cb->yournum, cb->yourid, Nr4states[cb->state]) ;
-
- tprintf("Window: %-5u Rxpect: %-5u RxNext: %-5u RxQ: %-5d %s\n",
- cb->window, uchar(cb->rxpected), uchar(cb->rxpastwin),
- len_p(cb->rxq), cb->qfull ? "RxCHOKED" : "") ;
-
- tprintf(" Unack: %-5u Txpect: %-5u TxNext: %-5u TxQ: %-5d %s\nTACK: ",
- cb->nbuffered, uchar(cb->ackxpected), uchar(cb->nextosend),
- len_q(cb->txq), cb->choked ? "TxCHOKED" : "") ;
-
- if (run_timer(&cb->tack))
- tprintf("%lu", read_timer(&cb->tack)) ;
- else
- tputs("-") ;
- tprintf("/%lu ms TChoke: ", dur_timer(&cb->tack)) ;
-
- if (run_timer(&cb->tchoke))
- tprintf("%lu", read_timer(&cb->tchoke)) ;
- else
- tputs("-") ;
- tprintf("/%lu ms TCD: ", dur_timer(&cb->tchoke)) ;
-
- if (run_timer(&cb->tcd))
- tprintf("%lu", read_timer(&cb->tcd)) ;
- else
- tputs("-") ;
-
- tprintf("/%lu ms\nTries: %u Inactive: %ld/%ld sec",
- dur_timer(&cb->tcd),
- cb->cdtries,
- read_timer(&cb->inactivity)/1000L,
- dur_timer(&cb->inactivity)/1000L);
-
- if(cb->blevel)
- tprintf(" Backoff Level %u",cb->blevel);
-
- tprintf("\nSRTT %ld ms Mean dev %ld ms\n", cb->srtt, cb->mdev) ;
-
- /* If we are connected and the send window is open, display */
- /* the status of all the buffers and their timers */
- if (cb->state == NR4STCON && cb->nextosend != cb->ackxpected) {
- tputs("TxBuffers: Seq Size Tries Timer\n") ;
-
- for (seq = cb->ackxpected ;
- nr4between(cb->ackxpected, seq, cb->nextosend) ;
- seq = (seq + 1) & NR4SEQMASK) {
-
- b = &cb->txbufs[seq % cb->window] ;
- t = &b->tretry ;
-
- if(tprintf(" %3u %3d %5d %lu/%lu\n",
- seq, len_p(b->data), b->retries + 1, read_timer(t), dur_timer(t))
- == EOF)
- break;
- }
- }
- }
-
- static int
- dominquality(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p ;
- {
- return setintrc(&(int16)Nr_autofloor,"MinQual",argc,argv,1,255);
- }
-
- /* Switch on/off saving of netrom routes to disk */
- static int
- doroutesave(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- return setbool(&Nr_save,"NET/ROM Route Save",argc,argv);
- }
-
- static char * near
- getarg(char *line)
- {
- char *arg;
- int c;
- static char *p;
-
- if (line) p = line;
- while (isspace(uchar(*p))) p++;
- arg = p;
- while (*p && !isspace(uchar(*p))) {
- c = (uchar(*p));
- *p++ = c;
- }
- if (*p) *p++ = '\0';
- return arg;
- }
- /*
- * Load saved NET/ROM routes - called at startup
- */
- int
- donrload(void)
- {
- FILE *fn;
- int quality, i, j;
- char buff[80], *alias = 0, *dest, *type, *iface, *neighbor;
- char ax25_alias[AXALEN], ax25_dest[AXALEN], ax25_nbor[AXALEN], *ptr;
-
- if((fn = open_file(Nrroutefile,READ_TEXT,0,1)) == NULLFILE)
- return 1;
-
- while(fgets(buff,80,fn) != NULL) {
- alias = dest = type = iface = neighbor = 0;
- quality = 0;
- if((ptr = strchr(buff,':')) == 0){
- *alias = '\0';
- dest = getarg(buff);
- } else {
- *ptr = ' ';
- alias = getarg(buff);
- dest = getarg(0);
- }
- type = getarg(0);
- quality = atoi(getarg(0));
- getarg(0);
- iface = getarg(0);
- neighbor = getarg(0);
-
- /* find interface */
- for(i = 0 ; i < Nr_numiface ; i++)
- if(!strcmp(Nrifaces[i].iface->name,iface))
- break ;
-
- if(i == Nr_numiface) {
- tprintf(Badif,iface);
- continue;
- }
-
- /* Convert to NET/ROM routing table formats */
- putalias(ax25_alias, alias, 0);
- setcall(ax25_dest, dest);
- setcall(ax25_nbor, neighbor);
-
- /* get and check quality value */
- if(quality > 255)
- quality = 255;
-
- if (strcmp(type,"P") == 0)
- j = 0;
- else
- j = 1;
-
- nr_routeadd(ax25_alias,ax25_dest,i,quality,ax25_nbor,!j,j);
- }
- fclose(fn);
- return 0;
- }
- /*
- * Save NET/ROM routes in file for reading when we start up again.
- * This function is called at each tick of the netrom obsotimer.
- *
- */
-
- int
- donrsave(void)
- {
- struct nrroute_tab *rp ;
- struct nr_bind *bp ;
- struct nrnbr_tab *np ;
- char neighbor[AXBUF], buf[18], *cp;
- int i;
- FILE *fn;
-
- #ifdef __TURBOC__
- if((fn = open_file(Nrroutefile,"wt+",0,1)) == NULLFILE)
- #else
- if((fn = open_file(Nrroutefile,"w+",0,1)) == NULLFILE)
- #endif
- return 1;
-
- for(i = 0 ; i < NRNUMCHAINS ; i++){
- for(rp = Nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rp->next){
- sprintf(buf,"%.*s",AXALEN,rp->alias) ;
- /* remove trailing spaces */
- if((cp = strchr(buf,' ')) == NULLCHAR)
- cp = &buf[strlen(buf)] ;
- if(cp != buf) /* don't include colon for null alias */
- *cp++ = ':' ;
- for(bp = rp->routes; bp != NULLNRBIND; bp = bp->next) {
- pax25(cp,rp->call) ;
- fprintf(fn,"%-16s ",buf) ;
- np = bp->via ;
- fprintf(fn,"%1s %3d %3d %-8s %s\n",
- (bp->flags & NRB_PERMANENT ? "P" :
- bp->flags & NRB_RECORDED ? "R" : "X"),
- bp->quality,bp->obsocnt,
- Nrifaces[np->iface].iface->name,
- pax25(neighbor,np->call));
- }
- }
- }
- fclose(fn);
- return 0;
- }
-
- /* Route command multiplexer */
- static int
- donrroute(argc, argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- struct cmds Routecmds[] = {
- "add", dorouteadd, 0, 6,
- "netrom route add <alias> <destination> <iface> <quality> <neighbor>",
- "drop", doroutedrop, 0, 4,
- "netrom route drop <destination> <neighbor> <iface>",
- "info", dorouteinfo, 0, 2,
- "netrom route info <destination>",
- "save", doroutesave, 0, 0,
- "netrom route save [<0|1>]",
- NULLCHAR,
- } ;
-
- if (argc < 2) {
- return doroutedump(9,0,p) ;
- }
- return subcmd(Routecmds,argc,argv,p) ;
- }
-
- /* Command multiplexer */
- int
- donetrom(argc,argv,p)
- int argc ;
- char *argv[] ;
- void *p;
- {
- struct cmds Nrcmds[] = {
- "acktime", donracktime, 0, 0, NULLCHAR,
- "bcnodes", dobcnodes, 0, 2, "netrom bcnodes <iface> [<call>]",
- "connect", donrconnect, 1024, 2, "netrom connect <node>",
- "choketime", donrchoketime, 0, 0, NULLCHAR,
- "close", donrclose, 0, 2, "netrom close <nrcb>",
- "derate", donrderate, 0, 0, NULLCHAR,
- "interface", dointerface, 0, 4,
- "netrom interface <iface> <alias> <quality>",
- "irtt", donrirtt, 0, 0, NULLCHAR,
- "kick", donrkick, 0, 2, "netrom kick <nrcb>",
- "minquality", dominquality, 0, 0, NULLCHAR,
- "nodefilter", donodefilter, 0, 0, NULLCHAR,
- "nodetimer", donodetimer, 0, 0, NULLCHAR,
- "obsotimer", doobsotimer, 0, 0, NULLCHAR,
- "promiscuous", donrpromisc, 0, 0, NULLCHAR,
- "qlimit", donrqlimit, 0, 0, NULLCHAR,
- "reset", donrreset, 0, 2, "netrom reset <nrcb>",
- "retries", donrretries, 0, 0, NULLCHAR,
- "route", donrroute, 0, 0, NULLCHAR,
- "status", donrstatus, 0, 0, NULLCHAR,
- "ttl", donrttl, 0, 0, NULLCHAR,
- "user", donruser, 0, 0, NULLCHAR,
- "verbose", donrverbose, 0, 0, NULLCHAR,
- "window", donrwindow, 0, 0, NULLCHAR,
- NULLCHAR,
- } ;
- return subcmd(Nrcmds,argc,argv,p) ;
- }
-
- #endif /* NETROM */
-